package qqhfpay

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"reflect"
	"sort"
	"strings"
)

var matchField = map[string]bool{
	"merchantNo":      true,
	"merchantOrderId": true,
	"channelCode":     true,
	"amount":          true,
	"currency":        true,
	"mobileNo":        true,
	"email":           true,
	"userName":        true,
	"notifyUrl":       true,
	"expireTime":      true,
}

func isEmptyValue(v interface{}) bool {
	// Check for nil or zero-value equivalent for the type of v.
	switch v.(type) {
	case string:
		return v == ""
	case int, int64:
		return v == 0
	case float64, float32:
		return v == 0
	case nil:
		return true
	default:
		return reflect.ValueOf(v).IsZero()
	}
}

func GenerateSignatureOfQqhf(params map[string]interface{}, secret string) (string, error) {
	var sortedKeys []string
	for k := range params {
		_, ok := matchField[k]
		if ok {
			sortedKeys = append(sortedKeys, k)
		}

	}
	sort.Strings(sortedKeys)

	var sortedParamStrBuilder strings.Builder
	for _, k := range sortedKeys {
		val := params[k]
		if k != "sign" && !isEmptyValue(val) {
			sortedParamStrBuilder.WriteString(k)
			sortedParamStrBuilder.WriteString("=")
			sortedParamStrBuilder.WriteString(fmt.Sprintf("%v", val)) // Convert any type to string
			sortedParamStrBuilder.WriteString("&")
		}
	}

	sortedParamStr := sortedParamStrBuilder.String()
	finalStr := sortedParamStr + "key=" + secret

	// HMAC-SHA256签名方式签名，签名完成后将字节数组转16进制编码成string
	h := hmac.New(sha256.New, []byte(secret))
	h.Write([]byte(finalStr))
	signature := h.Sum(nil)
	sign := hex.EncodeToString(signature)

	//fmt.Printf("sortedKeys: %s\nsortedParamStr: %s\nfinalStr: %s\nsign: %s\n", sortedKeys, sortedParamStr, finalStr, sign)
	return strings.ToLower(sign), nil
}
